﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LINQToolKit
{
    /// <summary>
    /// Represents the association collection
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <remarks>
    /// This framework is under the GNU licence and Creative Commons 3.0.
    /// You can also get a copy of the source code from google code
    /// <see cref="http://linqtodouban.googlecode.com/svn/trunk/"/>.
    /// For more information and further support, please contact with kevin (chwkai@gmail.com)
    /// </remarks>
    public sealed class AssociationSet<T> : AssociationObject<T>, IEnumerable<T>
    {
        private IEnumerable<T> _inner;
        private bool _loaded;

        public AssociationSet(IEnumerable<T> inner)
        {
            inner.AssertNull("inner");
            this._inner = inner ;
            this._loaded = true;
        }

        public AssociationSet(Uri source) : base(source)
        {
            this._loaded = false;
            this._inner = new List<T>();
        }

        public IEnumerable<T> Value
        {
            get
            {
                if (!this._loaded && this.IsReady)
                {
                    lock (this)
                    {
                        if (!this._loaded)
                        {
                            this._inner = (IEnumerable<T>)
                                this.Provider.Select(typeof(T), this.Source);
                            this._loaded = true;
                        }
                    }
                }

                return this._inner;
            }
        }

        public IEnumerator<T> GetEnumerator()
        {
            if (this.Value == null)
            {
                return (new List<T>()).GetEnumerator();
            }

            return this.Value.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return this.Value.GetEnumerator();
        }
    }
}
